﻿using DCMS.Core;
using DCMS.Core.Data;
using DCMS.Core.Domain.Products;
using DCMS.Core.Domain.WareHouses;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace DCMS.Services.Products
{
    public interface IProductService
    {
        void AdjustInventory(Product product, bool decrease, int quantity, string attributesXml);
        bool CheckExists(RecentPrice recentPrice);
        bool CombinationHasExists(int? productId);
        void DeleteCombination(Combination combination);
        void DeleteProduct(Product product);
        void DeleteProductCombination(ProductCombination productCombination);
        void DeleteProductPrice(ProductPrice productPrice);
        void DeleteProductTierPrice(List<ProductTierPrice> tierPrices);
        void DeleteProductTierPrice(ProductTierPrice tierPrice);
        void DeleteProductTierPricePlan(ProductTierPricePlan tierPricePlan);
        void DeleteRecentPrice(RecentPrice recentPrice);
        List<Brand> GetAllBrands(int? store, int[] ids);
        IPagedList<Combination> GetAllCombinations(int? store, string name = null, int pageIndex = 0, int pageSize = int.MaxValue);
        IList<Combination> GetAllCombinationsByStore(int? store);
        IList<Combination> GetAllHaveSubProductsCombinationsByStore(int? store);
        IList<Product> GetAllocationProducts(int store, int type, int[] categoryIds, int wareHouseId);
        IPagedList<ProductTierPricePlan> GetAllPlans(int storeId, string name = null, int pageIndex = 0, int pageSize = int.MaxValue);
        IList<ProductTierPricePlan> GetAllPlansByStore(int? store);
        IPagedList<ProductCombination> GetAllProductCombinations(int? store, string name = null, int pageIndex = 0, int pageSize = int.MaxValue);
        IList<ProductCombination> GetAllProductCombinationsByCombinationId(int? store, int? combinationId);
        IList<ProductCombination> GetAllProductCombinationsByStore(int? store);
        IList<ProductPrice> GetAllProductPrices();
        IList<ProductPrice> GetAllProductPrices(int storeId);
        IList<ProductPrice> GetAllProductPricesDisplayed(int pagesize = 0);
        IList<Product> GetAllProducts(int storeId);
        IList<Product> GetAllProductsDisplayed(int pagesize = 0);
        IPagedList<RecentPrice> GetAllRecentPrices(int? store, string productName = null, string customerName = "", int pageIndex = 0, int pageSize = int.MaxValue);
        IList<RecentPrice> GetAllRecentPricesByStore(int? store);
        Combination GetCombinationById(int combinationId);
        Combination GetCombinationByProductId(int? productId);
        IList<int> GetHasSoldProductIds(int storId, int ProductId);
        IList<Product> GetLowStockProducts(int supplierId);
        decimal GetNowWeightedAveragePrice(int pid, int num);
        IList<int> GetProductBrandIds(int Brandid);
        IList<Product> GetProductByIds(int? store, int[] productIds);
        Product GetProductById(int? store, int productId);
        Product GetProductByName(int store, string name);
        Product GetProductBySku(string sku);
        IList<ProductCategory> GetProductCategories(int stroId, int[] productIds);
        Task<IList<ProductCategory>> GetProductCategoriesAsync(int stroId, int[] productIds);
        ProductCombination GetProductCombinationById(int productCombinationId);
        IList<ProductTierPrice> GetProductCostPrice(int storeId, int referenceCostPrice, int averagePurchasePriceCalcNumber, IList<Product> allProducts);
        List<string> GetProductDates(int store, int productId, int wareHouseId);
        IList<ProductFlavor> GetProductFlavors(int stroId, int[] productIds);
        Task<IList<ProductFlavor>> GetProductFlavorsAsync(int stroId, int[] productIds);
        IList<int> GetProductIds(int Categoryid);
        IList<int> GetProductIds(int? store, string productName);
        IList<ProductManufacturer> GetProductManufacturers(int stroId, int[] productIds);
        Task<IList<ProductManufacturer>> GetProductManufacturersAsync(int stroId, int[] productIds);
        string GetProductName(int? store, int productId);
        IList<ProductPicture> GetProductPictures(int stroId, int[] productIds);
        Task<IList<ProductPicture>> GetProductPicturesAsync(int stroId, int[] productIds);
        ProductPrice GetProductPriceById(int? store, int productPriceId);
        ProductPrice GetProductPriceByProductIdAndUnitId(int? store, int productId, int unitId);
        Tuple<ProductPrice, ProductPrice, ProductPrice> GetProductPriceByUnit(int storeId, int productId, int smallUnitId, int strokeUnitId, int bigUnitId);
        Tuple<ProductPrice, ProductPrice, ProductPrice> GetProductPriceByUnit(Product product);
        IList<ProductPrice> GetProductPrices(int stroId, int[] productIds);
        Task<IList<ProductPrice>> GetProductPricesAsync(int stroId, int[] productIds);
        IList<ProductPrice> GetProductPricesByProductId(int? store, int productId);
        IList<ProductPrice> GetProductPricesByProductIds(int? store, int[] productIds, bool platform = false);
        IList<Product> GetProducts(out IList<int> filterableSpecificationAttributeOptionIds, bool loadFilterableSpecificationAttributeOptionIds = false, int pageIndex = 0, int pageSize = int.MaxValue, IList<int> categoryIds = null, int manufacturerId = 0, int storeId = 0, int supplierId = 0, int parentGroupedProductId = 0, ProductType? productType = null, bool visibleIndividuallyOnly = false, bool? featuredProducts = null, decimal? priceMin = null, decimal? priceMax = null, int productTagId = 0, string keywords = null, bool searchDescriptions = false, bool searchSku = true, bool searchProductTags = false, IList<int> filteredSpecs = null, ProductSortingEnum orderBy = ProductSortingEnum.Position, bool showHidden = false, bool specialprice = false);
        IList<Product> GetProductsByCatagoryId(int? store, int catagoryId);
        IList<Product> GetProductsByIds(int storeId, int[] productIds, bool platform = false);
        IList<ProductSpecificationAttribute> GetProductSpecificationAttributes(int stroId, int[] productIds);
        Task<IList<ProductSpecificationAttribute>> GetProductSpecificationAttributesAsync(int stroId, int[] productIds);
        ProductTierPrice GetProductTierPriceById(int tierPriceId);
        ProductTierPrice GetProductTierPriceById(int productId, int planId, int planType);
        ProductTierPrice GetProductTierPriceById(int store, int productId, int planId, int planType);
        IList<ProductTierPrice> GetProductTierPriceByProductId(int productId);
        IList<ProductTierPrice> GetProductTierPriceByProductIds(int? store, int[] productIds, bool platform = false);
        ProductTierPricePlan GetProductTierPricePlanById(int tierPriceId);
        IList<ProductTierPrice> GetProductTierPrices(int stroId, int[] productIds);
        Task<IList<ProductTierPrice>> GetProductTierPricesAsync(int stroId, int[] productIds);
        IList<ProductVariantAttributeCombination> GetProductVariantAttributeCombinations(int stroId, int[] productIds);
        Task<IList<ProductVariantAttributeCombination>> GetProductVariantAttributeCombinationsAsync(int stroId, int[] productIds);
        IList<ProductVariantAttribute> GetProductVariantAttributes(int stroId, int[] productIds);
        Task<IList<ProductVariantAttribute>> GetProductVariantAttributesAsync(int stroId, int[] productIds);
        RecentPrice GetRecentPrice(int store, int customerId, int productId);
        RecentPrice GetRecentPriceById(int recentPriceId);
        IList<int> GetStatisticalTypeid(int StatisticalTypeid);
        IList<Stock> GetStocks(int stroId, int[] productIds);
        Task<IList<Stock>> GetStocksAsync(int stroId, int[] productIds);
        IList<int> GetSubCategoryIds(int? store, int categoryId);
        void InsertCombination(Combination combination);
        void InsertProduct(IUnitOfWork uow, Product product);
        void InsertProduct(Product product);
        void InsertProductCombination(List<ProductCombination> productCombination);
        void InsertProductCombination(ProductCombination productCombination);
        void InsertProductFlavor(List<ProductFlavor> productFlavors);
        void InsertProductPrice(List<ProductPrice> productPrice);
        void InsertProductPrice(ProductPrice productPrice);
        void InsertProducts(List<Product> products);
        void InsertProductTierPrice(List<ProductTierPrice> tierPrice);
        void InsertProductTierPrice(ProductTierPrice tierPrice);
        void InsertProductTierPrice(ProductTierPricePlan tierPricePlan);
        void InsertRecentPrice(RecentPrice recentPrice);
        BaseResult ProductCreateOrUpdate(int storeId, int userId, int productId, Product product, List<ProductSpecificationAttribute> productSpecificationAttributes, List<ProductPrice> productPrices, List<ProductTierPrice> productTierPrices, List<ProductFlavor> productFlavors, Combination combination, List<ProductCombination> productCombinations);
        void RecordProductTierPriceLastPrice(int storeId, List<RecordProductPrice> recordProductPrices);
        void RecordRecentPriceLastPrice(int storeId, List<RecordProductPrice> recordProductPrices);
        IPagedList<Product> SearchProducts(int? storeId, int[] includes, int[] categoryIds, bool? usablequantity, bool? published, bool? hassold, bool includeCategories = true, bool includeManufacturers = true, bool includeSpecificationAttributes = true, bool includeVariantAttributes = true, bool includeVariantAttributeCombinations = true, bool includePrices = true, bool includeTierPrices = true, bool includePictures = true, bool includeStocks = true, bool includeFlavor = true, bool includeBrand = true, int wareHouseId = 0, string key = "", int productStatus = 2, int pageIndex = 0, int pageSize = int.MaxValue, int brandId = 0);
        void SetSolded(int productId);
        ProductUnitOption UnitConversion(int? storeId, Product product, int[] producIds);
        List<ProductUnitOptions> UnitConversions(int? storeId, List<Product> products, int[] producIds);
        void UpdateCombination(Combination combination);
        void UpdateProduct(Product product);
        void UpdateProducts(List<Product> products);
        void UpdateProductCombination(ProductCombination productCombination);
        void UpdateProductPrice(List<ProductPrice> productPrice);
        void UpdateProductPrice(ProductPrice productPrice);
        void UpdateProductTierPrice(ProductTierPrice tierPrice);
        void UpdateProductTierPricePlan(ProductTierPricePlan tierPricePlan);
        BaseResult UpdateRecentPrice(int storeId, int userId, List<RecentPrice> recentPrices);
        void UpdateRecentPrice(RecentPrice recentPrice);
        void BatchSetMnemonicCode(int storeId);
    }
}